package com.onenine.app.activity;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

import com.alibaba.sdk.android.manager.OssManager;
import com.chad.library.adapter.base.BaseItemDraggableAdapter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.onenine.app.R;
import com.onenine.app.adapter.ImageAddAdapter;
import com.onenine.app.listener.LastItemUnDragAndSwipeCallback;
import com.onenine.app.model.BarrageItem;
import com.onenine.app.request.SendBarrageRequest;
import com.onenine.app.response.UserInfoResponse;
import com.onenine.app.utils.DataType;
import com.onenine.app.utils.Permissions;
import com.onenine.app.utils.RoleResLoader;
import com.onenine.app.utils.UrlConfig;
import com.onenine.app.view.NVoiceBar;
import com.onenine.base.base.BaseActivity;
import com.onenine.base.okhttp.BaseResponse;
import com.onenine.base.okhttp.OkCallback;
import com.onenine.base.okhttp.OkRequest;
import com.onenine.base.utils.AppConfig;
import com.onenine.base.utils.Toasty;
import com.onenine.chat.emoji.Constants;
import com.onenine.chat.emoji.EmojiBean;
import com.onenine.chat.emoji.EmojiView;
import com.onenine.chat.emoji.EmoticonsKeyboardUtils;
import com.onenine.chat.emoji.data.EmoticonEntity;
import com.onenine.chat.emoji.listener.EmoticonClickListener;
import com.onenine.chat.emoji.widget.EmoticonsEditText;
import com.onenine.chat.rongcloud.RcUser;
import com.onenine.chat.util.SimpleCommonUtils;
import com.onenine.chat.view.AudioRecordButton;
import com.onenine.common.util.ApUtils;
import com.onenine.common.util.KeyboardUtils;
import com.onenine.common.util.SizeUtils;
import com.onenine.common.util.SoftKeyboardListener;
import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.engine.impl.GlideEngine;
import com.zhihu.matisse.internal.entity.CaptureStrategy;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * 发送弹幕
 */
public class SendBarrageActivity extends BaseActivity implements View.OnTouchListener, EmoticonClickListener, AudioRecordButton
        .AudioFinishRecorderListener, View.OnClickListener, EasyPermissions.PermissionCallbacks, SoftKeyboardListener
        .OnSoftKeyBoardChangeListener, OssManager.Callback, BaseQuickAdapter.OnItemClickListener, BaseQuickAdapter.OnItemChildClickListener {

    private static final int MAX_PHOTO_COUNT = 3;
    private EmoticonsEditText mEdtEmoji;
    private View mBtnEmoji, mBtnVoice, mBtnPhoto, mRlVoice;
    private EmojiView mEmojiView;
    private RecyclerView mRecyclerView;
    private NVoiceBar mVoiceBar;
    private AudioRecordButton mBtnRecord;
    private Button mBtnRetry;
    private boolean mKeyboardShow;
    private int mCompressCount, mCompressPosition;
    private BaseItemDraggableAdapter mImageAdapter;
    private List<String> mImagePaths = new ArrayList<>();

    @Override
    protected int getLayout() {
        return R.layout.activity_send_barrage;
    }

    @Override
    protected void initViews() {
        super.initViews();
        mToolbar.setLeftTitle(R.string.cancel);
        mToolbar.setRightTitle(R.string.send);
        mToolbar.setRightTitleBackground(RoleResLoader
                .getRoleDrawableResourceId(RoleResLoader
                        .DynamicResName.THEME_GRADIENT_CORNER_BG), true);
        mEdtEmoji = findViewById(R.id.edt_content);
        mBtnRecord = findViewById(R.id.btn_voice);
        mBtnRecord.setTextColor(RoleResLoader
                .getRoleColorResourceId(RoleResLoader.DynamicResName.THEME_COLOR));
        mBtnRecord.setBackgroundResource(RoleResLoader
                .getRoleDrawableResourceId(RoleResLoader
                        .DynamicResName.THEME_STROKE_WHITE_CORNER));
        mRlVoice = findViewById(R.id.rl_voice);
        mBtnRecord.setAudioFormat(false);
        mBtnEmoji = findViewById(R.id.btn_emoji);
        mBtnPhoto = findViewById(R.id.btn_photo);
        mEmojiView = findViewById(R.id.ev_emoji_bar);
        mVoiceBar = findViewById(R.id.bv_voice);
        mVoiceBar.setSexStyle(RcUser.getInstance().getSex(), false);
        mBtnRetry = findViewById(R.id.btn_retry);
        mBtnVoice = findViewById(R.id.btn_audio);
        SimpleCommonUtils.initEmoticonsEditText(mEdtEmoji);
        mImagePaths.add(UploadImageActivity.IMAGE_ADD);
        mEmojiView.setAdapter(SimpleCommonUtils
                .getCommonAdapter(this, this));
        mRecyclerView = findViewById(R.id.rv_image);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        mImageAdapter = new ImageAddAdapter(mImagePaths, (AppConfig.SCREEN_WIDTH - SizeUtils.dp2px(72)) / 3);
        mRecyclerView.setAdapter(mImageAdapter);
        mImageAdapter.setOnItemClickListener(this);
        mImageAdapter.setOnItemChildClickListener(this);
        mImageAdapter.enableDragItem(new LastItemUnDragAndSwipeCallback(mRecyclerView, mImageAdapter).getItemTouchHelper());
        onTouch(mEdtEmoji, null);
    }

    @Override
    protected void initListeners() {
        super.initListeners();
        SoftKeyboardListener.setListener(this, this);
        mToolbar.setOnRightClickListener(this);
        mBtnRecord.setAudioFinishRecorderListener(this);
        mBtnEmoji.setOnClickListener(this);
        mBtnPhoto.setOnClickListener(this);
        mEdtEmoji.setOnTouchListener(this);
        mBtnVoice.setOnClickListener(this);
        mBtnRetry.setOnClickListener(this);
    }

    @Override
    protected void initData() {
        super.initData();
        mEmojiView.setAdapter(SimpleCommonUtils
                .getCommonAdapter(this, this));
    }

    private void showEmojiLayout() {
        mEmojiView.setVisibility(View.VISIBLE);
    }

    private boolean isEmojiLayoutVisible() {
        return mEmojiView.getVisibility() == View.VISIBLE;
    }

    private void dismissEmojiLayout() {
        mEmojiView.setVisibility(View.GONE);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId() == R.id.edt_content) {
            if (!mEdtEmoji.isFocused()) {
                mEdtEmoji.setFocusable(true);
                mEdtEmoji.setFocusableInTouchMode(true);
            }
        }
        if (isEmojiLayoutVisible()) {
            dismissEmojiLayout();
        }
        return false;
    }

    @Override
    public void onEmoticonClick(Object o, int actionType, boolean isDelBtn) {
        if (isDelBtn) {
            SimpleCommonUtils.delClick(mEdtEmoji);
        } else {
            if (o == null) {
                return;
            }
            if (actionType == Constants.EMOTICON_CLICK_BIGIMAGE) {
            } else {
                String content = null;
                if (o instanceof EmojiBean) {
                    content = ((EmojiBean) o).emoji;
                } else if (o instanceof EmoticonEntity) {
                    content = ((EmoticonEntity) o).getContent();
                }

                if (TextUtils.isEmpty(content)) {
                    return;
                }
                int index = mEdtEmoji.getSelectionStart();
                Editable editable = mEdtEmoji.getText();
                editable.insert(index, content);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == 101) {
                hideBarrageVoiceView();
                showBarrageImageView();
                compressImages(Matisse.obtainPathResult(data));
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    /**
     * 打开相册
     */
    private void launchAlbum() {
        if (mImagePaths.size() >= MAX_PHOTO_COUNT + 1) {
            Toasty.showNormal(getString(R.string.album_max_count_limit_hint, MAX_PHOTO_COUNT));
            return;
        }
        int size = AppConfig.SCREEN_WIDTH / 3 - SizeUtils.dp2px(10);
        Matisse.from(this)
                .choose(MimeType.ofImage())//只显示照片
                .capture(true)
                .captureStrategy(new CaptureStrategy(true, getPackageName() + ".fileprovider"))
                .countable(false)//无序选择图片
                .showSingleMediaType(true)
                .maxSelectable(MAX_PHOTO_COUNT - mImagePaths.size() + 1)//最大选择数量
                .gridExpectedSize(size)//图片显示表格的大小getResources()
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)//图像选择和预览活动所需的方向。
                .thumbnailScale(0.85f)//缩放比例
                .theme(R.style.Matisse_Light)//主题
                .imageEngine(new GlideEngine())//加载方式
                .forResult(101);//请求码
    }

    /**
     * 压缩图片在100kb左右
     *
     * @param images
     */
    private void compressImages(List<String> images) {
        mCompressCount = images.size();
        mCompressPosition = 0;
        Luban.with(this)
                .load(images).ignoreBy(100)
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onSuccess(File file) {
                        mCompressPosition++;
                        mImagePaths.add(0, file.getPath());
                        mImageAdapter.notifyItemInserted(0);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                }).launch();
    }

    /**
     * 是否压缩完毕
     *
     * @return
     */
    protected boolean isImageCompressed() {
        return mCompressPosition >= mCompressCount;
    }

    @Override
    public void onSuccess(String url) {
        //oss上传完毕
        if (isBarrageImageVisible()) {
            //带图片
            updateLoadingMsg();
            submitData("", url);
        } else if (isBarrageVoiceVisible()) {
            //带语音
            updateLoadingMsg();
            submitData(url, "");
        }
    }

    /**
     * 更新加载文本
     */
    private void updateLoadingMsg() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                replaceLoading(getString(R.string.barrage_sending));
            }
        });
    }

    @Override
    public void onProgress(float progress) {

    }

    @Override
    public void onFailure(int errorCode, String errorMsg) {
        dismissLoading();
        Toasty.showNormal(errorMsg);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        if (requestCode == UploadImageActivity.REQ_OPEN_CAMERA
                && perms.size() == Permissions.CAMERA_ALBUM_PERMISSIONS.length) {
            launchAlbum();
        }
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).setTitle(getString(R.string.permission_apply))
                    .setRationale(getString(R.string.permission_refuse_always_hint)).build().show();
        } else if (requestCode == UploadImageActivity.REQ_OPEN_CAMERA) {
            Toasty.showNormal(R.string.permission_camera_hint);
        }
    }

    @Override
    public void keyBoardShow(int height) {
        mKeyboardShow = true;
        mEmojiView.getLayoutParams().height = height;
    }

    @Override
    public void keyBoardHide(int height) {
        mKeyboardShow = false;
    }

    @Override
    public void onBackPressed() {
        if (isEmojiLayoutVisible()) {
            dismissEmojiLayout();
        } else if (mKeyboardShow) {
            EmoticonsKeyboardUtils.closeSoftKeyboard(mEdtEmoji);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_right_title:
                //发送弹幕
                boolean isImageVisible = isBarrageImageVisible();
                boolean isVoiceVisible = isBarrageVoiceVisible();
                if (mEdtEmoji.getText().length() == 0 && !isImageVisible && !isVoiceVisible) {
                    Toasty.showNormal(mEdtEmoji.getHint());
                    return;
                }
                if (isImageVisible) {
                    //带图片
                    if (!isImageCompressed()) {
                        Toasty.showNormal(R.string.wait_for_image_compress);
                        return;
                    }
                    showLoading(R.string.image_dealing);
                    ArrayList<String> uploadList = new ArrayList<>(mImagePaths);
                    uploadList.remove(UploadImageActivity.IMAGE_ADD);
                    OssManager.getInstance(ApUtils.getApp())
                            .ossUpload(uploadList, new ArrayList<>(), this);
                } else if (isVoiceVisible) {
                    //带语音
                    showLoading(R.string.voice_dealing);
                    OssManager.getInstance(ApUtils.getApp()).ossUpload(new ArrayList<String>() {{
                        add(mVoiceBar.getTag(R.id.data_tag).toString());
                    }}, new ArrayList<>(), this);
                } else {
                    //文本
                    showLoading();
                    submitData("", "");
                }
                break;
            case R.id.btn_photo:
                if (EasyPermissions.hasPermissions(this, Permissions.CAMERA_ALBUM_PERMISSIONS)) {
                    launchAlbum();
                } else {
                    EasyPermissions.requestPermissions(this, getString(R.string.permission_extra_storage_hint)
                            , UploadImageActivity.REQ_OPEN_CAMERA, Permissions.CAMERA_ALBUM_PERMISSIONS);
                }
                break;
            case R.id.btn_emoji:
                if (isEmojiLayoutVisible()) {
                    dismissEmojiLayout();
                } else if (mKeyboardShow) {
                    EmoticonsKeyboardUtils.closeSoftKeyboard(mEdtEmoji);
                    mEdtEmoji.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            showEmojiLayout();
                        }
                    }, 100);
                } else {
                    showEmojiLayout();
                }
                break;
            case R.id.iv_image:
                hideBarrageImageView();
                break;
            case R.id.btn_audio:
                hideBarrageImageView();
                if (mRlVoice.getVisibility() != View.VISIBLE) {
                    showVoiceRecordButton();
                }
                break;
            case R.id.btn_retry:
                showVoiceRecordButton();
                break;
        }

    }

    @Override
    public void onFinished(float seconds, String filePath) {
        hideBarrageImageView();
        showBarrageVoiceView(filePath, seconds);
    }

    /**
     * 图片可见
     *
     * @return
     */
    private boolean isBarrageImageVisible() {
        return mImagePaths.size() > 1;
    }

    /**
     * 语音可见
     *
     * @return
     */
    private boolean isBarrageVoiceVisible() {
        return mVoiceBar.getTag(R.id.data_tag) != null;
    }

    /**
     * 显示图片
     */
    private void showBarrageImageView() {
        mRecyclerView.setVisibility(View.VISIBLE);
    }

    /**
     * 隐藏图片
     */
    private void hideBarrageImageView() {
        mRecyclerView.setVisibility(View.GONE);
        mImagePaths.clear();
        mImagePaths.add(UploadImageActivity.IMAGE_ADD);
        mImageAdapter.notifyDataSetChanged();
    }

    /**
     * 显示录制按钮
     */
    private void showVoiceRecordButton() {
        mRlVoice.setVisibility(View.VISIBLE);
        mVoiceBar.setVisibility(View.INVISIBLE);
        mBtnRetry.setVisibility(View.GONE);
        mBtnRecord.setVisibility(View.VISIBLE);
        mVoiceBar.setTag(R.id.data_tag, null);
    }

    /**
     * 显示语音条
     *
     * @param filePath
     * @param seconds
     */
    private void showBarrageVoiceView(String filePath, float seconds) {
        if (mVoiceBar.getVisibility() == View.VISIBLE) {
            return;
        }
        mVoiceBar.setVisibility(View.VISIBLE);
        mBtnRetry.setVisibility(View.VISIBLE);
        mVoiceBar.setTag(R.id.data_tag, filePath);
        mVoiceBar.setData(filePath, seconds);
        mBtnRecord.setVisibility(View.GONE);
    }

    /**
     * 隐藏语音条
     */
    private void hideBarrageVoiceView() {
        mVoiceBar.setTag(R.id.data_tag, null);
        mRlVoice.setVisibility(View.GONE);
        mVoiceBar.setVisibility(View.INVISIBLE);
    }

    /**
     * 发布弹幕
     *
     * @param voiceUrl
     * @param imageUrl
     */
    private void submitData(String voiceUrl, String imageUrl) {
        final SendBarrageRequest request = new SendBarrageRequest();
        request.setUserId(RcUser.getInstance().getUserId());
        request.setContent(mEdtEmoji.getText().toString());
        request.setVoiceUrl(voiceUrl);
        request.setPictureUrl(imageUrl);
        OkRequest.getInstance().withUrl(UrlConfig.SEND_BARRAGE)
                .withRequest(request).doRequest(SendBarrageActivity
                .class.getSimpleName(), new OkCallback<BaseResponse>() {
            @Override
            public void onResponse(BaseResponse response, String srcData) {
                dismissLoading();
                if (response.isSuccess()) {
                    Toasty.showNormal(R.string.send_success);
                    postNewBarrageItem(request);
                    finish();
                } else {
                    Toasty.showNormal(response.getMessage());
                }
            }
        });
    }

    /**
     * 添加一条弹幕至弹幕库
     *
     * @param request
     */
    private void postNewBarrageItem(SendBarrageRequest request) {
        BarrageItem barrageItem = new BarrageItem();
        barrageItem.setUserId(request.getUserId());
        barrageItem.setContent(request.getContent());
        //fixme 这里的图片路径和语音路径为本地直拼URL，待处理
        barrageItem.setPictureUrl(UrlConfig.IMAGE_SERVER_URL + request.getPictureUrl());
        barrageItem.setVoiceUrl(UrlConfig.IMAGE_SERVER_URL + request.getVoiceUrl());
        UserInfoResponse userInfoResponse = RcUser.getInstance().getInfoResponse();
        if (userInfoResponse != null) {
            barrageItem.setPhoto(userInfoResponse.getPhoto());
            barrageItem.setNickName(userInfoResponse.getNickName());
            barrageItem.setCityName(userInfoResponse.getCityName());
            barrageItem.setSex(userInfoResponse.getSex());
        }
        if (TextUtils.isEmpty(request.getContent())) {
            if (!TextUtils.isEmpty(request.getPictureUrl())) {
                barrageItem.setBarrageType(DataType.BARRAGE_IMAGE);
            } else {
                barrageItem.setBarrageType(DataType.BARRAGE_VOICE);
            }
        } else {
            if (!TextUtils.isEmpty(request.getPictureUrl())) {
                barrageItem.setBarrageType(DataType.BARRAGE_IMAGE_TEXT);
            } else if (!TextUtils.isEmpty(request.getVoiceUrl())) {
                barrageItem.setBarrageType(DataType.BARRAGE_VOICE_TEXT);
            } else {
                barrageItem.setBarrageType(DataType.BARRAGE_TEXT);
            }
        }
        EventBus.getDefault().post(barrageItem);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mBtnRecord.setAudioFinishRecorderListener(null);
        mBtnRecord = null;
    }

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        mImageAdapter.remove(position);
        mRecyclerView.requestLayout();
    }

    @Override
    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        if (position == mImagePaths.size() - 1) {
            KeyboardUtils.hideSoftInput(this);
            mBtnPhoto.callOnClick();
        } else if (position >= 0) {
            ArrayList<String> urls = new ArrayList<>(mImageAdapter.getData());
            urls.remove(urls.size() - 1);
            BrowserImageActivity.launchActivity(this, urls, position);
        }
    }

    @Override
    public void finish() {
        super.finish();
        //fixme 不能为何style已配置activityCloseEnterAnimation退出动画不生效，这里显示处理
        overridePendingTransition(0, R.anim.slide_out_bottom);
    }

}
